define(function(require) {

    var github = require('model/github');

    var homeTpl = require('../tpl/home.tpl');
    var blogsTpl = require('../tpl/blogs.tpl');
    var projectsTpl = require('../tpl/projects.tpl');
    var labTpl = require('../tpl/lab.tpl');
    var componentsTpl = require('../tpl/components.tpl');
    var pptsTpl = require('../tpl/ppts.tpl');

    var highlightedList = [];

    var router = {};
    router.tplBase = '../tpl/';
    router.map = {
        'home': {
            name: 'Home',
            tpl: homeTpl,
            getData: function(cb) {
                var location = window.location;
                cb({
                    link: location.origin + location.pathname + 'lab/flash.html'
                });
            }
        },
        'blogs': {
            name: 'Blogs',
            tpl: blogsTpl,
            getData: function(cb) {
                require('marked');
                require('rainbow');
                github.listBlogs(function(blogs) {
                    _.each(blogs, function(blog) {
                        blog.body = marked(blog.body);
                    });
                    if (window.location.hash == '#' + router.state) {
                        cb({
                            blogs: blogs
                        });
                    }
                });
            }
        },
        'projects': {
            name: 'Projects',
            tpl: projectsTpl,
            getData: function(cb) {
                github.listProjects(function(events){
                    cb({
                        events: events
                    });
                });
            }
        },
        'lab': {
            name: 'Lab',
            tpl: labTpl,
            getData: function(cb) {
                github.debugJSON(function(pens){
                    cb({
                        pens: pens
                    });
                });
            }
        },
        'components': {
            name: 'Components',
            tpl: componentsTpl,
            getData: function(cb) {
                var cards = require('cards');
                github.listRepos(function(repos){
                    var forkedRepos = _.filter(repos, function(repo){
                        return repo.fork;
                    });
                    var myRepos = _.filter(repos, function(repo){
                        return !repo.fork;
                    });
                    cb({
                        repos : [
                            {
                                type: 'Mine',
                                items: myRepos
                            },
                            {
                                type: 'Forked',
                                items: forkedRepos
                            }
                        ]
                    });
                    cards.init('.card', '.dropdown-item a');
                });
            }
        },
        'ppts': {
            name: 'PPTs',
            tpl: pptsTpl,
            getData: function(cb) {
                cb(null);
            }
        }
    };

    function renderCode() {
        $('code').each(function() {
            var $code = $(this),
                cls = $code.attr('class'),
                language;
            if(typeof cls === 'undefined') {
                return;
            }
            language = cls.split('-')[1];
            $code.attr('data-language', language);
        });
        Rainbow.color();
    }

    router.renderState = function() {
        var hash = window.location.hash;
        var state = hash.slice(1);
        ('' == state) && (state = 'home');
        if (router.map[state]) {
            router.state = state;
            var stateHash = router.map[state];
            !stateHash && (stateHash = router.map['']);
            var tpl = stateHash.tpl;
            $('#nav a[href="' + hash + '"]').parent().addClass('active');
            stateHash.getData(function(model) {
                var output = Mustache.render(tpl, model);
                $('#content').html(output);
                ('blogs' == state) && renderCode();
            });
        }
    };

    router.init = function(debug) {
        router.bind();
        router.initNavbars();
        !debug && router.renderState();
    };

    router.initNavbars = function() {
        var HTML = '';
        for (var key in router.map) {
            HTML += '<li><a href="#' + key + '">' + router.map[key].name + '</a></li>';
        }
        $('#nav').html(HTML);
    };

    router.bind = function() {
        if ("onhashchange" in window) {
            window.onhashchange = function() {
                router.renderState();
            };
        } else {
            var prevHash = window.location.hash;
            window.setInterval(function() {
                if (window.location.hash != prevHash) {
                    prevHash = window.location.hash;
                    router.renderState();
                }
            }, 500);
        }
    };

    return router;
});
